package dao

import (
	"context"
	"fmt"

	"go.mongodb.org/mongo-driver/bson/primitive"

	"go.mongodb.org/mongo-driver/mongo/options"

	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
)

type Mongo struct {
	col         *mongo.Collection
	newObjectID func() primitive.ObjectID
}

func NewMongo(db *mongo.Database) *Mongo {
	return &Mongo{
		col:         db.Collection("account"),
		newObjectID: primitive.NewObjectID,
	}
}

func (m *Mongo) ResolveAccountID(account string, password string) (string, error) {
	res := m.col.FindOneAndUpdate(context.Background(), bson.M{
		"account":  account,
		"password": password,
	}, bson.M{
		//"$set": bson.M{
		//	"account":  account,
		//	"password": password,
		//},
		"$setOnInsert": bson.M{
			"_id":      m.newObjectID(),
			"account":  account,
			"password": password,
		},
	}, options.FindOneAndUpdate().
		SetUpsert(true).
		SetReturnDocument(options.After),
	)

	if res.Err() != nil {
		return "", fmt.Errorf("can not findOneAndUpdate: %v", res.Err())
	}

	var row struct {
		ID primitive.ObjectID `bson:"_id"`
	}
	err := res.Decode(&row)
	if res.Err() != nil {
		return "", fmt.Errorf("can not decode result: %v", err)
	}

	return row.ID.Hex(), nil
}
